package com.mtiiot.fsmanage.server;

import com.mtiiot.fsmanage.bean.common.ChartSeries;
import com.mtiiot.fsmanage.bean.common.TableDataInfo;
import com.mtiiot.fsmanage.bean.metadata.ftp.FtpStatisticsData;
import com.mtiiot.fsmanage.bean.metadata.ftp.FtpStatisticsGroup;
import com.mtiiot.fscore.utils.StringUtil;
import com.mtiiot.fsmanage.core.dao.BaseElasticsearch;
import com.mtiiot.fsmanage.utils.Contants;
import com.mtiiot.fsmanage.utils.TimeUtil;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.client.Client;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.metrics.stats.InternalStats;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Created by Administrator on 16-8-18.
 */
@Service
@Transactional
public class FastdfsServer {
    @Autowired
    private BaseElasticsearch baseElasticsearch;
    private static String INDEX = Contants.INDEX_METADATA;
    private static String TYPE = Contants.TYPE_METADATA_FASTDFS;

    public Object fastdfsQuery(String sysName, String l1Name, String l2Name, String l3Name, String times, String queryKeyWord, int count, String sort) throws Exception {
        Client client = null;
        try {
            client = baseElasticsearch.getEsDataSource().getClient();
            BoolQueryBuilder bq = QueryBuilders.boolQuery();
            if (!StringUtil.isEmpty(sysName)) {
                bq.must(QueryBuilders.termQuery("sysName", sysName));                 // Query
            }
            if (!StringUtil.isEmpty(l1Name)) {
                bq.must(QueryBuilders.termQuery("l1Name", l1Name));
            }
            if (!StringUtil.isEmpty(l2Name)) {
                bq.must(QueryBuilders.termQuery("l2Name", l2Name));
            }
            if (!StringUtil.isEmpty(l3Name)) {
                bq.must(QueryBuilders.termQuery("l3Name", l3Name));
            }
            if (!StringUtil.isEmpty(queryKeyWord)) {
                bq.must(QueryBuilders.queryStringQuery(queryKeyWord));
            }
            long[] l = TimeUtil.handleTimes(times);
            if (l != null && l.length > 0) {
                bq.must(QueryBuilders.rangeQuery("time").from(l[0]).to(l[1]));
            }
            QueryBuilder queryBuilder = bq;
            SortOrder sortOrder=null;
            if("desc".equals(sort)){
                sortOrder=SortOrder.DESC;
            }else{
                sortOrder=SortOrder.ASC;
            }
            SearchRequestBuilder srb = client.prepareSearch(INDEX)
                    .setTypes(TYPE)
                            //按时间降序号
                    .addSort("time", sortOrder)
                    .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
                            // 设置查询数据的位置,分页用
                    .setFrom(0)
                            // 设置查询结果集的最大条数
                    .setSize(count)
                            // 设置是否按查询匹配度排序
                    .setExplain(true);
            // 最后就是返回搜索响应信息
            srb.setQuery(bq);


            TableDataInfo tdif=new TableDataInfo();
            SearchResponse response =srb.execute().actionGet();
            SearchHits searchHits = response.getHits();
            tdif.setCount(searchHits.totalHits());
            SearchHit[] hits = searchHits.getHits();

            List<Map<String, Object>> sms=new ArrayList<Map<String, Object>>();
            for (SearchHit searchHit : hits) {
                Map<String, Object> sm = searchHit.sourceAsMap();
                sms.add(sm);
            }
            tdif.setObject(sms);
            return tdif;
        } finally {
            if (client != null) {
                baseElasticsearch.getEsDataSource().releaseClient(client);
            }
        }
    }

    public Object fastdfsStatistics(String sysName, String l1Name, String l2Name, String l3Name, String times) throws Exception {
        Client client = null;
        try {
            client = baseElasticsearch.getEsDataSource().getClient();
            BoolQueryBuilder bq = QueryBuilders.boolQuery();
            if (!StringUtil.isEmpty(sysName)) {
                bq.must(QueryBuilders.termQuery("sysName", sysName));                 // Query
            }
            if (!StringUtil.isEmpty(l1Name)) {
                bq.must(QueryBuilders.termQuery("l1Name", l1Name));
            }
            if (!StringUtil.isEmpty(l2Name)) {
                bq.must(QueryBuilders.termQuery("l2Name", l2Name));
            }
            if (!StringUtil.isEmpty(l3Name)) {
                bq.must(QueryBuilders.termQuery("l3Name", l3Name));
            }
            long[] l = TimeUtil.handleTimes(times);
            if (l != null && l.length > 0) {
                bq.must(QueryBuilders.rangeQuery("time").from(l[0]).to(l[1]));
            }

            QueryBuilder queryBuilder = bq;
            SearchRequestBuilder srb = client.prepareSearch(INDEX)
                    .setTypes(TYPE)
                            //按时间降序号
                    .addSort("time", SortOrder.DESC)
                    .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
                            // 设置查询数据的位置,分页用
                    .setFrom(0)
                            // 设置查询结果集的最大条数
                    .setSize(500)
                            // 设置是否按查询匹配度排序
                    .setExplain(true);
            // 最后就是返回搜索响应信息
            srb.setQuery(bq);

            String aggTremName = "tremAgg";
            String aggStatsName = "statsAgg";
            String statsType = null;
            if (StringUtil.isEmpty(sysName)) {
                //统计系统级别的
                srb.addAggregation(AggregationBuilders.terms(aggTremName).field("sysName").subAggregation(AggregationBuilders.stats(aggStatsName).field("requestSize")));
                statsType = "sysName";
            } else {
                if (StringUtil.isEmpty(l1Name)) {
                    //统计l1级别的
                    srb.addAggregation(AggregationBuilders.terms(aggTremName).field("l1Name").subAggregation(AggregationBuilders.stats(aggStatsName).field("requestSize")));
                    statsType = "l1";
                } else {
                    if (StringUtil.isEmpty(l2Name)) {
                        //统计l2级别的
                        srb.addAggregation(AggregationBuilders.terms(aggTremName).field("l2Name").subAggregation(AggregationBuilders.stats(aggStatsName).field("requestSize")));
                        statsType = "l2";
                    } else {
                        //统计l3级别的
                        srb.addAggregation(AggregationBuilders.terms(aggTremName).field("l3Name").subAggregation(AggregationBuilders.stats(aggStatsName).field("requestSize")));
                        statsType = "l3";
                    }
                }
            }
            SearchResponse response = srb.execute().actionGet();
            Aggregations sysAggr = response.getAggregations();
            Terms sysNameAgg = sysAggr.get(aggTremName);
            List<Terms.Bucket> list = sysNameAgg.getBuckets();
            FtpStatisticsGroup fsg = new FtpStatisticsGroup();
            List<FtpStatisticsData> fsds = new ArrayList<FtpStatisticsData>();
            String[] chartCategories = new String[list.size()];
            Long[] requestCountArr = new Long[list.size()];
            Double[] requestSizeArr = new Double[list.size()];
            FtpStatisticsData fsd = null;
            int i = 0;
            for (Terms.Bucket tb : list) {
                Aggregations statsAggr = tb.getAggregations();
                InternalStats is = statsAggr.get(aggStatsName);
                String keyValue = tb.getKey().toString();
                chartCategories[i] = keyValue;
                requestCountArr[i] = is.getCount();
                requestSizeArr[i] = is.getSum();
                fsd = new FtpStatisticsData();
                if ("sysName".equals(statsType)) {
                    fsd.setSysName(keyValue);
                } else if ("l1".equals(statsType)) {
                    fsd.setSysName(sysName);
                    fsd.setL1Name(keyValue);
                } else if ("l2".equals(statsType)) {
                    fsd.setSysName(sysName);
                    fsd.setL1Name(l1Name);
                    fsd.setL2Name(keyValue);
                } else if ("l3".equals(statsType)) {
                    fsd.setSysName(sysName);
                    fsd.setL1Name(l1Name);
                    fsd.setL2Name(l2Name);
                    fsd.setL3Name(keyValue);
                }
                fsd.setRequestCount(is.getCount());
                fsd.setRequestSize(is.getSum());
                fsds.add(fsd);
                i++;
            }
            fsg.setLsds(fsds);
            fsg.setChartCategories(chartCategories);
            List<ChartSeries> css = new ArrayList<ChartSeries>();
            if (requestCountArr.length > 0) {
                ChartSeries cs1 = new ChartSeries();
                cs1.setName("请求");
                cs1.setData(requestCountArr);
                css.add(cs1);
                cs1 = new ChartSeries();
                cs1.setName("流量");
                cs1.setData(requestSizeArr);
                css.add(cs1);
            }
            fsg.setCss(css);
            return fsg;
        } finally {
            if (client != null) {
                baseElasticsearch.getEsDataSource().releaseClient(client);
            }
        }
    }

}

